-
Notifications
You must be signed in to change notification settings - Fork 138
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Introduce Sqrt
on NumberType
#3055
base: master
Are you sure you want to change the base?
Conversation
Codecov ReportAttention: Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## master #3055 +/- ##
==========================================
+ Coverage 80.59% 80.68% +0.08%
==========================================
Files 379 380 +1
Lines 91159 91659 +500
==========================================
+ Hits 73472 73957 +485
+ Misses 15053 15052 -1
- Partials 2634 2650 +16
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Sentry. |
Haven't added any tests yet. Opened it up for some early feedback.
|
Nice work!
Maybe we can introduce a Math library/contract? (similar to existing RLP, BLS, Crypto, etc.; similar to how there's a "math" package in some languages). |
@turbolent I like both the ideas. @SupunS @dsainati1 Do you have opinions? I'll go with a separate math contract if both seem fine to you all. |
A |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am less familiar with fixed point numbers, so my confusion maybe it is just my lack of context. Nevertheless, it might be useful to add some documentation making it easier for other people reading to code to follow, even if they are not experts in fixed-point number arithmetics. Please see my suggestions above (specifically this and this comment)
Co-authored-by: Alexander Hentschel <[email protected]>
Thanks for the review comments @AlexHentschel. Have incorporated your comments. PTAL again, thanks! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👏
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great work and nice documentation 👌🏼
I left a few comments below.
|
||
func BigIntSqrt(interpreter *Interpreter, value *big.Int, locationRange LocationRange) UFix64Value { | ||
if value.Sign() < 0 { | ||
panic(UnderflowError{ |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unlike the overflow case where the result can't fit into the target type, this case corresponds to an "undefined" case rather than an underflow. The square root being non defined for negative inputs (similar to the division by zero error where dividing by zero isn't mathematically defined).
There doesn't seem to be an "undefined" error available so I see why underflow was used, but I wanted to mention this.
// This is because of the above check with sema.MaxSquareIntegerBig. | ||
valueFloat := new(big.Float).SetPrec(256).SetInt(value) | ||
res := new(big.Float).SetPrec(256).SetMode(big.ToZero).Sqrt(valueFloat) | ||
res.Mul(res, new(big.Float).SetPrec(256).SetInt(sema.Fix64FactorBig)) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
new(big.Float).SetPrec(256).SetInt(Fix64FactorBig)
could be a global constant defined like Fix64FactorBig
.
func (v Fix64Value) Sqrt(interpreter *Interpreter, locationRange LocationRange) UFix64Value { | ||
val := new(big.Int).SetUint64(uint64(v)) | ||
sqrtWithFix64FactorSqrt := BigIntSqrt(interpreter, val, locationRange) | ||
sqrt := sqrtWithFix64FactorSqrt / fixedpoint.Fix64FactorSqrt |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Possible optimization: I think we can save this division if in the function BigIntSqrt
(L163), we multiply by Fix64FactorSqrt
instead of Fix64Factor
, only in the case of Fix64Value
and UFix64Value
. For the rest of the types, we can keep multiplying by Fix64Factor
.
// So we can support Sqrt till 34028236692093846346337 since | ||
// Sqrt(34028236692093846346337) = 184467440737.09551615999875115311 | ||
// which gets rounded down to 184467440737.09551615 | ||
// Sqrt(34028236692093846346338) = 184467440737.09551616000146165854 |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
👌🏼
}) | ||
} | ||
|
||
if value.Cmp(sema.MaxSquareIntegerBig) == 1 { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When calling this check in the case of Fix64Value
and UFix64Value
, I think we would exclude some values because value
is larger than the max, but in reality it represents a number less than max
(because value
is multiplied by the factor). Actually, I think all Fix64
and UFix64
values are less than the max
, so the result (square root) can always fit.
If I didn't miss anything and my comment makes sense, it may be better to have a specific function BigIntSqrtFloat
to process the case of UFix64
and Fix64
skipping the overflow (also to add the optimization from my previous comment)
Work towards #1151
Description
Introduce
Sqrt
onNumberType
defined in aMath
contract.UnderflowError
ifvalue < 0
.OverflowError
if the result does not fit in aUFix64
.master
branchFiles changed
in the Github PR explorer